package core

import (
	"mudsv/core/evt"
	"time"
)

type ISv interface {
	Init()
	Run()
	Destroy()
	Name() string
}

type SvCore struct {
	Signal            *Signal
	Serves            []ISv
	initializedServes []ISv // 执行过init的Serve
	SvTime            time.Time
	EventExecMap      map[evt.EvType]func(*evt.Evt) //事件类型回调列表
}

func NewSvCore() *SvCore {
	s := new(SvCore)
	s.Signal = NewSignal()
	s.EventExecMap = make(map[evt.EvType]func(*evt.Evt))
	return s
}

var _SvCore = NewSvCore()

// GetSvCore get master server entity
func GetSvCore() *SvCore {
	return _SvCore
}

// AddSv 向core中添加Svr
func AddSv(servers ...ISv) {
	_SvCore.AddSv(servers...)
}

// StartSv start all registered Serves
func StartSv() {
	_SvCore.StartSv()
}

// AddSv 向core中添加Sv
func (sm *SvCore) AddSv(servers ...ISv) {
	for _, server := range servers {
		sm.Serves = append(sm.Serves, server)
	}
}

// StartSv start all registered Serves
func (sm *SvCore) StartSv() {
	//if len(sm.Serves) == 0 {
	//	log.Panic("no server add!!!")
	//}

	defer func() {
		// FILO
		for index := len(sm.initializedServes) - 1; index >= 0; index-- {
			destroy(sm.initializedServes[index])
		}
		close(sm.Signal.Stopped)
	}()

	for _, server := range sm.Serves {
		sm.initializedServes = append(sm.initializedServes, server)
		server.Init()
		// 这里的网络层要和依赖区分开
		go server.Run()
		//coroutine.Go(func() { server.Run() })
	}
	<-sm.Signal.Stop
}

// safety destroy server
func destroy(server ISv) {
	defer func() {
		if err := recover(); err != nil {
		}
	}()
	server.Destroy()
}
